home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
reform16.zip
/
REFORMAT.IN5
< prev
next >
Wrap
Text File
|
1990-03-03
|
42KB
|
1,151 lines
{-------------------- REFORMAT.IN5 -------------------------------------------}
{Disk, FAT, directory, misc. routines}
{v1.6 Rewrote Check_DOS_Version to permit user override
of precautionary abort for DOS versions above v3.10
}
PROCEDURE ResetDisk;
{ flush buffers that weren't written }
BEGIN
(* In Turbo:
Register.ah := $0D;
msdos(Register);
*)
InLine(
$B4/$0D { mov ah,$0D ;reset disk}
/$CD/$21 { int $21}
);
END; { of ResetDisk }
PROCEDURE ResetSubdirectory;
{ DOS might not remember }
{
The directory information DOS provided us with does not contain the
driveletter, nor starts it with a backslash.
}
BEGIN
Move(CurrentDirectory[0], CurrentDirectory[3], 61);
CurrentDirectory[0] := DriveLetter;
CurrentDirectory[1] := ':';
CurrentDirectory[2] := '\';
(* in Turbo:
Register.ah := $3B;
Register.ds := Seg(CurrentDirectory);
Register.dx := Ofs(CurrentDirectory);
MSDos(Register);
*)
Inline(
$B4/$3B {mov ah,$3B}
/$BA/>CURRENTDIRECTORY {mov dx,>CurrentDirectory}
/$CD/$21 {int $21}
);
END; { of ResetSubDirectory }
{----------------------- general disk I/O routines -------------------------}
PROCEDURE Read_Write_Sectors(sectorNumber, numberOfSectors : Word; {v1.6 INTEGER;}
action : Disk_Activity);
VAR
intNr : INTEGER;
FUNCTION CarryFlag: BOOLEAN;
BEGIN
CarryFlag := Register.flags AND $01 <> 0;
END; { of CarryFlag }
BEGIN
WITH Register DO REPEAT
al := driveNumber;
cx := numberOfSectors;
dx := sectorNumber;
ds := Seg(DTAddress^);
bx := Ofs(DTAddress^);
IF action = reading
THEN BEGIN
intNr := $25;
NrStr := 'Error Reading Disk....';
END
ELSE BEGIN
intNr := $26;
NrStr := 'Error Writing Disk....';
AlreadyWritten := TRUE; { set it now because the first write
might succeed partially! }
END;
int2526(intNr); { 25H = read, 26H = write }
IF CarryFlag THEN BEGIN
S40 := 'Enter A (abort), R (retry)';
IF NOT AlreadyWritten THEN BEGIN
WriteWarning('No data lost!');
WriteError(NrStr);
Legals := 'AR';
END
ELSE BEGIN
WriteError('Probably loss of data!');
WriteDisaster(NrStr);
S40 := S40 + ', I(gnore)';
Legals := 'ARI';
END;
REPEAT
Getinput(S40,Instr);
UNTIL POS(Instr,Legals) <> 0;
IF Instr = 'A' THEN BEGIN
GotoXY(1,24); WRITELN; {leave the screen for him or her }
HALT;
END
ELSE BlankFields;
END;
UNTIL NOT CarryFlag;
END; { of Read_Write_Sectors }
PROCEDURE ReadCluster(clusterNumber: word);
VAR sectorNumber: word;
BEGIN
(* v1.6
sectorNumber := W_add(W_mul( clusterSize, clusterNumber - 2 ),
firstDataSector);
*)
sectorNumber := (clusterSize * (clusterNumber-2)) + firstDataSector; {v1.6}
Read_Write_Sectors(sectorNumber, clusterSize,reading);
END; { of ReadCluster }
PROCEDURE WriteCluster(clusterNumber: word);
VAR sectorNumber: word;
BEGIN
(* v1.6
sectorNumber := W_add(W_mul( clusterSize, clusterNumber - 2 ),
firstDataSector);
*)
sectorNumber := (clusterSize * (clusterNumber-2)) + firstDataSector; {v1.6}
Read_Write_Sectors(sectorNumber, clusterSize, writing);
END; { of WriteCluster }
{----------------------- disk information routines -------------------------}
PROCEDURE ReadBootSector(VAR DTArea: Buffer);
{
Read the bootsector from disk.
}
VAR
BootInfo: Boot Absolute DTArea;
BEGIN
WriteLog('Reading Bootsector.');
Read_Write_Sectors(0, 1, reading);
FOR count := 0 TO 7 DO
OEM[count] := Bootinfo.OEM[count];
totalSectors := Bootinfo.totalSectors;
trackSize := Bootinfo.trackSize;
hiddenSectors := Bootinfo.hiddenSectors;
END; { of ReadBootSector }
PROCEDURE GetInformation;
{
Ask DOS for information about the specified drive.
If we have an error return code from DOS we assume
that the disk specified was invalid.
We are using a number of DOS int 21H functions:
1) function 19H : returns current default drive in al: 0 = a, ..
2) function 32H : ! undocumented function !
returns a parameter table which is laid out
in the type Parameter_Table.
3) function 36H : several, but we only use the disk free space
4) function 47H : current working directory.
the remainder of the information we want to have or need, we find
in the disks bootrecord and in the FAT (bad space and used space).
}
VAR
ValidDrive: BOOLEAN;
Parms: Parms_32;
BEGIN
IF Instr = ' '
THEN GetInput('Enter drive letter',Instr);
WriteLog('Reading Disk Information');
{
get current disk: MS-DOS function call 19h
information is returned in AL: 0 = A, 1 = B, etc.
}
WITH Register DO BEGIN
(* in Turbo:
ah := $19; { DOS returns the default drive in al }
MSDos(Register); { as: 0 = A, 1 = B .... }
defaultDrive := al;
*)
Inline(
$B4/$19 {mov ah,$19}
/$CD/$21 {int $21}
/$A2/>DEFAULTDRIVE {mov [>defaultDrive],al}
);
ValidDrive := FALSE;
REPEAT { keep trying until a good letter }
IF ORD(Instr) < 64 THEN Instr := CHR($FF);
DriveLetter := UpCase(Instr);
driveNumber := ORD(DriveLetter) - 64; { A = 65, so A = 1, B = 2, ...... }
ah := $36;
dl := driveNumber; { must be 0 = default, 1 = A, 2 = B .. }
MSDos(Register);
IF ax <> $ffff THEN ValidDrive := TRUE
ELSE BEGIN
WriteWarning('Invalid driveletter!');
GetInput('Enter new letter',Instr);
WriteWarning(' ');
END;
UNTIL ValidDrive;
freeClusters := bx; { we can find that only here }
{
In case the drive to be reformatted has a current working directory
DOS may lose track of the current working directory. So we will get
the current working directory and will tell DOS what it is, when
we are done.
}
dl := driveNumber; { must be 0 = default, 1 = A, 2 = B .. }
ds := Seg(CurrentDirectory);
si := Ofs(CurrentDirectory);
ah := $47; { DOS returns current working directory}
MSDos(Register); { no error, drive checked before }
{
We now use the undocumented DOS function call 32H. It was described in the
May 86 PC Tech Journal article "Finding Disk Parameters" by
Glenn F. Roberts.
}
dl := driveNumber; { must be 0 = default, 1 = A, 2 = B .. }
ah := $32;
MSDos(Register);
Parms := Ptr( ds, bx);
sectorSize := Parms^.sectorSize;
media := Parms^.MediaDescriptor;
numberOfHeads := SUCC(Parms^.numberOfHeads_1);
reservedSectors := Parms^.reservedSectors;
rootDirSize := Parms^.rootDirSize;
numberOfFATs := Parms^.numberOfFATs;
fatSize := Parms^.fatSize;
clusterSize := SUCC(Parms^.clusterSize_1);
firstDataSector := Parms^.firstDataSector;
firstDirectorySector := Parms^.firstDirectorySector;
totalDataClusters := PRED(Parms^.totalDataClusters_1);
(* v1.6
BigFAT := W_cmp(totalDataClusters, Gt, 4086);
*)
BigFAT := (totalDataClusters > 4086); {v1.6}
END; {of with Register}
IF BigFAT THEN BEGIN
unused := $0000;
reservedMinimum := $FFF0;